package com.atguigu.ssyx.acl.service.impl;


import com.atguigu.ssyx.acl.mapper.PermissionMapper;
import com.atguigu.ssyx.acl.mapper.RolePermissionMapper;
import com.atguigu.ssyx.acl.service.PermissionService;
import com.atguigu.ssyx.acl.service.RolePermissionService;
import com.atguigu.ssyx.acl.utils.PermissionHelper;
import com.atguigu.ssyx.model.acl.Permission;
import com.atguigu.ssyx.model.acl.RolePermission;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 权限服务实现类
 * </p>
 */
@Service
@RequiredArgsConstructor

public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission>
        implements PermissionService {


    private final RolePermissionMapper rolePermissionMapper;
    private final RolePermissionService rolePermissionService;

    @Override
    public List<Permission> queryAllMenu() {
        //1.查询所有菜单
        List<Permission> allList = baseMapper.selectList(null);
        //2.调用方法查询所有有层级格式的菜单
        List<Permission> result = PermissionHelper.build(allList);
        return result;
    }


    //根据菜单Id递归删除菜单
    @Override
    public boolean removeChildById(Long id) {

        //1.创建list集合idList，封装要所有删除的菜单id
        ArrayList<Long> idList = new ArrayList<>();
        idList.add(id);
        //2.根据当前的菜单id，获取当前菜单下面的所有子菜单
        //如果子菜单下面还有子菜单，都要获取到
        //重点：递归找当前菜单下的所有子菜单

        this.getAllPermissionId(id, idList);


        //调用方法根据多个菜单id，删除菜单
        baseMapper.deleteBatchIds(idList);
        return true;

    }


    private void getAllPermissionId(Long id, ArrayList<Long> idList) {
        //1.根据当前菜单id，查询当前菜单下面的所有子菜单
        LambdaQueryWrapper<Permission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Permission::getPid, id);
        //获取到了当前菜单下面的所有子菜单
        List<Permission> list = baseMapper.selectList(wrapper);
        //递归找当前菜单下面的所有子菜单，因为可能当前菜单下有子菜单
        for (Permission permission : list) {

            //封装菜单id到集合中
            idList.add(permission.getId());
            //递归找当前菜单下面的所有子菜单
            getAllPermissionId(permission.getId(), idList);
        }

    }


    //1.查询所有菜单列表
    //2.查询角色分配的菜单列表
    @Override
    public Map<String, Object> findPermissionByRoleId(Long roleId) {


        //1.查询所有菜单列表
        List<Permission> allPermissions = queryAllMenu();
        //2.在角色和菜单的关系表中查询，根据角色id查出已经分配的菜单id列表
        List<Long> assignPermissionIdList = baseMapper.selectRolePermissionByRoleId(roleId);
        //创建出一个集合，分配已分配的菜单列表
        ArrayList<Permission> assignPermissons = new ArrayList<>();
        //遍历所有菜单列表，拿着每一个菜单的id和已经分配的菜单id列表进行对比
        for (Permission permission : allPermissions) {
            //拿着每一个菜单的id和已经分配的菜单id列表进行对比
            if (assignPermissionIdList.contains(permission.getId())) {
                //如果包含，则添加到分配的菜单列表中
                assignPermissons.add(permission);
            }
        }
        //返回所有菜单列表 和 分配的菜单列表


        Map<String, Object> map = Map.of("allPermissions", allPermissions, "assignPermissons", assignPermissons);
        return map;


    }

    @Override
    public void saveRolePermission(Long roleId, List<Long> permissionIds) {
        //1.根据角色id删除之前的分配过的菜单
        LambdaQueryWrapper<RolePermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RolePermission::getRoleId, roleId);
        rolePermissionMapper.delete(wrapper);

        //2.重新添加角色分配的菜单
        //2.1创建集合，封装角色分配的菜单
        List<RolePermission> rolePermissions = new ArrayList<>();
        //2.遍历所有菜单id，拿到每一个菜单id，封装到角色和菜单的关系表中
        for (Long permissionId : permissionIds) {
            RolePermission rolePermission = new RolePermission();
            rolePermission.setRoleId(roleId);
            rolePermission.setPermissionId(permissionId);
            rolePermissions.add(rolePermission);
        }
        //3.保存到角色和菜单的关系表中
        rolePermissionService.saveBatch(rolePermissions);


    }
}